﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Gmantis.Controls
{
    public class TreeViewLinePanel : Canvas
    {
        // Fields
        public static readonly DependencyProperty LineDashArrayProperty = DependencyProperty.Register("LineDashArray", typeof(DoubleCollection), typeof(TreeViewLinePanel), new PropertyMetadata(null, new PropertyChangedCallback(TreeViewLinePanel.OnLineDashArrayPropertyChanged)));
        public static readonly DependencyProperty LineStrokeProperty = DependencyProperty.Register("LineStroke", typeof(Brush), typeof(TreeViewLinePanel), new PropertyMetadata(new SolidColorBrush(Colors.Black), new PropertyChangedCallback(TreeViewLinePanel.OnLineStrokePropertyChanged)));
        public static readonly DependencyProperty LineStyleProperty = DependencyProperty.Register("LineStyle", typeof(Style), typeof(TreeViewLinePanel), new PropertyMetadata(new PropertyChangedCallback(TreeViewLinePanel.OnLineStylePropertyChanged)));
        public static readonly DependencyProperty LineThicknessProperty = DependencyProperty.Register("LineThickness", typeof(double), typeof(TreeViewLinePanel), new PropertyMetadata(1.0, new PropertyChangedCallback(TreeViewLinePanel.OnLineThicknessPropertyChanged)));

        // Methods
        public TreeViewLinePanel()
        {
            SetCustomDefaultValues();
        }

        private void LinePanel_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            RectangleGeometry geometry = new RectangleGeometry
            {
                Rect = new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight)
            };
            base.Clip = geometry;
            base.Children.Clear();
            double num = 0.0;
            while (base.ActualHeight > 0.0)
            {
                TreeViewLine target = new TreeViewLine();
                target.SetBinding<TreeViewLinePanel>(FrameworkElement.StyleProperty, this, x => x.LineStyle);
                target.SetBinding<TreeViewLinePanel>(TreeViewLine.StrokeProperty, this, x => x.LineStroke);
                target.SetBinding<TreeViewLinePanel>(TreeViewLine.StrokeThicknessProperty, this, x => x.LineThickness);
                target.SetBinding<TreeViewLinePanel>(TreeViewLine.StrokeDashArrayProperty, this, x => x.LineDashArray);
                base.Children.Add(target);
                target.SetValue(Canvas.TopProperty, num);
                target.Measure(new Size(base.ActualWidth, base.ActualHeight));
                num += target.DesiredSize.Height;
                if ((num >= base.ActualHeight) || (target.DesiredSize.Height == 0.0))
                {
                    return;
                }
            }
        }

        private static void OnLineDashArrayPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TreeViewLinePanel panel = d as TreeViewLinePanel;
            DoubleCollection oldValue = (DoubleCollection)e.OldValue;
            DoubleCollection newValue = (DoubleCollection)e.NewValue;
            if (newValue != oldValue)
            {
                panel.InvalidateMeasure();
            }
        }

        private static void OnLineStrokePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TreeViewLinePanel panel = d as TreeViewLinePanel;
            Brush oldValue = (Brush)e.OldValue;
            Brush newValue = (Brush)e.NewValue;
            if (newValue != oldValue)
            {
                panel.InvalidateMeasure();
            }
        }

        private static void OnLineStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TreeViewLinePanel panel = d as TreeViewLinePanel;
            Style oldValue = (Style)e.OldValue;
            Style newValue = (Style)e.NewValue;
            if (newValue != oldValue)
            {
                panel.InvalidateMeasure();
            }
        }

        private static void OnLineThicknessPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TreeViewLinePanel panel = d as TreeViewLinePanel;
            double oldValue = (double)e.OldValue;
            double newValue = (double)e.NewValue;
            if (newValue != oldValue)
            {
                panel.InvalidateMeasure();
            }
        }

        private void SetCustomDefaultValues()
        {
            base.SizeChanged += new SizeChangedEventHandler(this.LinePanel_SizeChanged);
        }

        // Properties
        public DoubleCollection LineDashArray
        {
            get { return (DoubleCollection)GetValue(LineDashArrayProperty); }
            set { SetValue(LineDashArrayProperty, value); }
        }

        public Brush LineStroke
        {
            get { return (Brush)GetValue(LineStrokeProperty); }
            set { SetValue(LineStrokeProperty, value); }
        }

        public Style LineStyle
        {
            get { return (Style)GetValue(LineStyleProperty); }
            set { SetValue(LineStyleProperty, value); }
        }

        public double LineThickness
        {
            get { return (double)GetValue(LineThicknessProperty); }
            set { SetValue(LineThicknessProperty, value); }
        }
    }
}
